using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Microsoft.Phone.Controls.Primitives
{
	[TemplatePart(Name = "ContentPresenter", Type = typeof(ContentPresenter)), TemplatePart(Name = "LocalTransform", Type = typeof(TranslateTransform)), TemplatePart(Name = "PanningTransform", Type = typeof(TranslateTransform)), TemplatePart(Name = "RightWraparound", Type = typeof(Rectangle)), TemplatePart(Name = "LeftWraparound", Type = typeof(Rectangle))]
	public class PanningLayer : ContentControl
	{
		private const string LocalTransformName = "LocalTransform";
		private const string PanningTransformName = "PanningTransform";
		private const string LeftWraparoundName = "LeftWraparound";
		private const string RightWraparoundName = "RightWraparound";
		private const string ContentPresenterName = "ContentPresenter";
		protected static readonly Duration Immediately = new Duration(TimeSpan.Zero);
		private readonly IEasingFunction _easingFunction;
		private ContentPresenter contentPresenter;
		private TransformAnimator animator;
		private bool isStatic;
		protected TranslateTransform LocalTransform
		{
			get;
			set;
		}
		protected TranslateTransform PanningTransform
		{
			get;
			set;
		}
		protected Rectangle LeftWraparound
		{
			get;
			set;
		}
		protected Rectangle RightWraparound
		{
			get;
			set;
		}
		protected internal ContentPresenter ContentPresenter
		{
			get
			{
				return this.contentPresenter;
			}
			set
			{
				if (this.contentPresenter != null)
				{
					this.contentPresenter.remove_SizeChanged(new SizeChangedEventHandler(this.OnContentSizeChanged));
				}
				this.contentPresenter = value;
				if (this.contentPresenter != null)
				{
					this.contentPresenter.add_SizeChanged(new SizeChangedEventHandler(this.OnContentSizeChanged));
				}
			}
		}
		protected virtual double PanRate
		{
			get
			{
				return 1.0;
			}
		}
		internal bool IsStatic
		{
			get
			{
				return this.isStatic;
			}
			set
			{
				if (value != this.isStatic)
				{
					this.isStatic = value;
					if (this.isStatic)
					{
						this.ActualOffset = 0.0;
						return;
					}
					this.UpdateWrappingRectangles();
				}
			}
		}
		internal Panorama Owner
		{
			get;
			set;
		}
		internal double ActualOffset
		{
			get
			{
				if (this.PanningTransform == null)
				{
					return 0.0;
				}
				return this.PanningTransform.get_X();
			}
			private set
			{
				if (this.PanningTransform != null)
				{
					this.PanningTransform.set_X(value);
				}
			}
		}
		public PanningLayer()
		{
			ExponentialEase exponentialEase = new ExponentialEase();
			exponentialEase.set_Exponent(5.0);
			this._easingFunction = exponentialEase;
			base..ctor();
			PerfLog.BeginLogMarker(PerfMarkerEvents.MPC_PANO_STARTUP, PerfLog.PanningLayer);
			base.set_DefaultStyleKey(typeof(PanningLayer));
			base.add_Loaded(new RoutedEventHandler(this.PanningLayer_Loaded));
		}
		private void PanningLayer_Loaded(object sender, RoutedEventArgs e)
		{
			base.remove_Loaded(new RoutedEventHandler(this.PanningLayer_Loaded));
			PerfLog.EndLogMarker(PerfMarkerEvents.MPC_PANO_STARTUP, PerfLog.PanningLayer);
		}
		public override void OnApplyTemplate()
		{
			PerfLog.BeginLogMarker(PerfMarkerEvents.MPC_PANO_APPLYTEMPLATE, PerfLog.PanningLayer);
			base.OnApplyTemplate();
			this.LocalTransform = (base.GetTemplateChild("LocalTransform") as TranslateTransform);
			this.PanningTransform = (base.GetTemplateChild("PanningTransform") as TranslateTransform);
			this.LeftWraparound = (base.GetTemplateChild("LeftWraparound") as Rectangle);
			this.RightWraparound = (base.GetTemplateChild("RightWraparound") as Rectangle);
			this.ContentPresenter = (base.GetTemplateChild("ContentPresenter") as ContentPresenter);
			this.animator = ((this.PanningTransform != null) ? new TransformAnimator(this.PanningTransform) : null);
			PerfLog.EndLogMarker(PerfMarkerEvents.MPC_PANO_APPLYTEMPLATE, PerfLog.PanningLayer);
		}
		protected override Size MeasureOverride(Size availableSize)
		{
			PerfLog.BeginLogMarker(PerfMarkerEvents.MPC_PANO_MEASURE, PerfLog.PanningLayer);
			Size result = base.MeasureOverride(availableSize);
			PerfLog.EndLogMarker(PerfMarkerEvents.MPC_PANO_MEASURE, PerfLog.PanningLayer);
			return result;
		}
		protected override Size ArrangeOverride(Size finalSize)
		{
			PerfLog.BeginLogMarker(PerfMarkerEvents.MPC_PANO_ARRANGE, PerfLog.PanningLayer);
			Size result = base.ArrangeOverride(finalSize);
			PerfLog.EndLogMarker(PerfMarkerEvents.MPC_PANO_ARRANGE, PerfLog.PanningLayer);
			return result;
		}
		public void GoTo(int targetOffset, Duration duration, Action completionAction)
		{
			if (this.animator != null && !this.IsStatic)
			{
				this.animator.GoTo((double)((int)((double)targetOffset * this.PanRate)), duration, this._easingFunction, completionAction);
			}
		}
		public virtual void Wraparound(int direction)
		{
			if (direction < 0)
			{
				this.GoTo((int)((this.ActualOffset + this.ContentPresenter.get_ActualWidth()) / this.PanRate), PanningLayer.Immediately, null);
				return;
			}
			this.GoTo((int)((this.ActualOffset - this.ContentPresenter.get_ActualWidth()) / this.PanRate), PanningLayer.Immediately, null);
		}
		internal void Refresh()
		{
			this.UpdateWrappingRectangles();
		}
		protected virtual void UpdateWrappingRectangles()
		{
			PerfLog.BeginLogMarker(PerfMarkerEvents.MPC_PANO_UPDATEWRAPPING, PerfLog.PanningLayer);
			ItemsPresenter itemsPresenter = base.get_Content() as ItemsPresenter;
			bool flag = itemsPresenter == null || this.Owner.Panel == null || this.Owner.Panel.VisibleChildren.get_Count() < 3;
			UIElement arg_6C_0 = this.LeftWraparound;
			Visibility visibility;
			this.RightWraparound.set_Visibility(visibility = ((this.IsStatic || !flag) ? 1 : 0));
			arg_6C_0.set_Visibility(visibility);
			if (!this.IsStatic && flag)
			{
				FrameworkElement arg_A3_0 = this.RightWraparound;
				double actualHeight;
				this.LeftWraparound.set_Height(actualHeight = this.ContentPresenter.get_ActualHeight());
				arg_A3_0.set_Height(actualHeight);
				FrameworkElement arg_CA_0 = this.RightWraparound;
				double width;
				this.LeftWraparound.set_Width(width = (double)this.Owner.ViewportWidth);
				arg_CA_0.set_Width(width);
				FrameworkElement arg_F0_0 = this.LeftWraparound;
				Thickness margin;
				this.RightWraparound.set_Margin(margin = this.ContentPresenter.get_Margin());
				arg_F0_0.set_Margin(margin);
				WriteableBitmap writeableBitmap = new WriteableBitmap(this.Owner.ViewportWidth, (int)this.ContentPresenter.get_ActualHeight());
				TranslateTransform translateTransform = new TranslateTransform();
				writeableBitmap.Render(this.ContentPresenter, translateTransform);
				writeableBitmap.Invalidate();
				Shape arg_142_0 = this.RightWraparound;
				ImageBrush imageBrush = new ImageBrush();
				imageBrush.set_ImageSource(writeableBitmap);
				arg_142_0.set_Fill(imageBrush);
				writeableBitmap = new WriteableBitmap(this.Owner.ViewportWidth, (int)this.ContentPresenter.get_ActualHeight());
				translateTransform.set_X((double)this.Owner.ViewportWidth - this.ContentPresenter.get_ActualWidth());
				writeableBitmap.Render(this.ContentPresenter, translateTransform);
				writeableBitmap.Invalidate();
				Shape arg_1AC_0 = this.LeftWraparound;
				ImageBrush imageBrush2 = new ImageBrush();
				imageBrush2.set_ImageSource(writeableBitmap);
				arg_1AC_0.set_Fill(imageBrush2);
			}
			if (this.LocalTransform != null)
			{
				double num = (this.LeftWraparound.get_Visibility() == null) ? (-this.LeftWraparound.get_Width() - this.LeftWraparound.get_Margin().get_Left()) : 0.0;
				this.LocalTransform.set_X(this.IsStatic ? 0.0 : (num - this.LeftWraparound.get_Margin().get_Right()));
			}
			PerfLog.EndLogMarker(PerfMarkerEvents.MPC_PANO_UPDATEWRAPPING, PerfLog.PanningLayer);
		}
		private void OnContentSizeChanged(object sender, SizeChangedEventArgs e)
		{
			this.UpdateWrappingRectangles();
		}
	}
}
